<?php

namespace asyncService;

use asyncService\lib\multiProcess;
use asyncService\processHandles\parentHandle;
use asyncService\processHandles\subHandle;
use asyncService\service\abstractService;

class mainService
{
    const EVENT_DATA = 1;
    const EVENT_STOP = 2;

    public $services = [];

    public $process;

    protected $_process_number = 1;

    function registerService(abstractService $service){
        $this->services[]  = $service;
        $this->_process_number= $this->_process_number+$service->process_number;
    }

    function run(){

        $process_number = ceil($this->_process_number);

        $this->process = $process = new multiProcess($process_number,$this->getMultiProcessMessageKey());

        $process->bindParentCallback(function ($worker){

        	$handle = new parentHandle($worker,$this);
            $handle->handle();

        });

        $process->bindSubCallback(function ($worker){

	        $handle = new subHandle($worker,$this);
	        $handle->handle();

        });

        $process->run();
    }

    function listenMessage($worker){

	    for($i=0;$i<=100;$i++){
		    foreach($this->services as $place => $service){
			    if($message = $service->pop()){
				    $worker->push(json_encode([self::EVENT_DATA,['p'=>$place,$message]]));
			    }
		    }
	    }

    }

    function StopServices(){
        foreach($this->services as $service){
	        $this->stopService($service);
        }
    }

    function stopService(abstractService $service){
        $this->process->push(['a'=>'stop',"d"=>get_class($service)]);
    }

    function getServiceKey(){
        $ips = swoole_get_local_ip();
        $key = array_pop($ips);

        foreach($this->services as $service){
            $key .= get_class($service);
        }

        return $key;
    }

    function getMultiProcessMessageKey(){
        return "__MESSAGE_".time()+rand(1,220);
    }

    function stop(){
        $mess = \asyncService\message\messageFactory::Produce();
        $a = $this->getServiceKey();
        $mess->sendSignal($a);
    }
}